package cn.iocoder.yudao.module.vos.controller.app.marketingscore;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.vos.controller.app.marketingscore.vo.MarketingListUpdateReqVO;
import cn.iocoder.yudao.module.vos.controller.app.marketingscore.vo.MarketingScorePhoneMd5RespVO;
import cn.iocoder.yudao.module.vos.service.marketingscore.app.MarketingScoreApiService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "开放接口 - 名单评分（仅返回phoneMd5）")
@RestController
@RequestMapping("/marketing")
@Validated
@Slf4j
@RequiredArgsConstructor
public class MarketingScoreApiController {

    private final MarketingScoreApiService marketingScoreApiService;

    @GetMapping("/page")
    @Operation(summary = "分页获取当日高分名单（仅返回phoneMd5，受账号随路限额）")
    public CommonResult<PageResult<MarketingScorePhoneMd5RespVO>> page(HttpServletRequest request,
                                                                       @Valid PageParam pageParam,
                                                                       @RequestParam(value = "date", required = false) String date) {
        // 日期固定为“当日（马尼拉时区）”默认昨天（这里按服务端 LocalDate 处理，若需要严格时区可在 Service 层引入 ZoneId.of("Asia/Manila")）
        LocalDate targetDate = StrUtil.isBlank(date)
                ? LocalDate.now()
                : LocalDate.parse(date);

        String appSecret = request.getHeader("appSecret");
        String ip = ServletUtil.getClientIP(request);
        PageResult<MarketingScorePhoneMd5RespVO> page =
                marketingScoreApiService.pageTopByDay(appSecret, pageParam, ip, targetDate);
        return success(page);
    }

    @PostMapping(value = "/update", consumes = "application/json")
    @Operation(summary = "更新响应状态和响应时间（含账号校验与扣费记账）")
    public CommonResult<Boolean> update(HttpServletRequest request,
                                        @RequestBody @Valid MarketingListUpdateReqVO req) {
        try {
            // 1) appSecret 仅从 Header 读取
            final String appSecret = request.getHeader("appSecret");
            if (StrUtil.isBlank(appSecret)) {
                log.warn("[/marketing/update] 缺少 appSecret header");
                return success(false);
            }

            // 2) 解析响应时间（优先 yyyy-MM-dd HH:mm:ss；兼容 epoch 秒/毫秒）
            LocalDateTime responseDateTime = parseResponseTime(req.getResponseTime());

            // 3) 获取客户端 IP（用于扣费日志）
            String ip = ServletUtil.getClientIP(request);

            // 4) 统一走 Service：账号校验（permission=marketing_list_update）→ 定价 → 业务更新 → 记账
            boolean updated = marketingScoreApiService.updateResponseWithCharge(
                    appSecret, req.getPhoneMd5(), req.getResponseState(), responseDateTime, ip);

            return success(updated);
        } catch (Exception e) {
            log.error("[/marketing/update] 更新失败 phoneMd5={}, err={}",
                    req != null ? req.getPhoneMd5() : "null", e.getMessage(), e);
            return success(false);
        }
    }

    /** 支持 "yyyy-MM-dd HH:mm:ss" 或 epoch 秒/毫秒 */
    private LocalDateTime parseResponseTime(String s) {
        if (StrUtil.isBlank(s)) {
            throw new IllegalArgumentException("responseTime 不能为空");
        }
        // 1) yyyy-MM-dd HH:mm:ss
        try {
            DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            return LocalDateTime.parse(s, fmt);
        } catch (Exception ignore) { }

        // 2) epoch（纯数字）
        if (StrUtil.isNumeric(s)) {
            long v = Long.parseLong(s);
            // 粗略判断位数：10位≈秒，13位≈毫秒
            if (s.length() <= 10) {
                return LocalDateTime.ofEpochSecond(v, 0, java.time.ZoneOffset.UTC);
            } else {
                return LocalDateTime.ofInstant(java.time.Instant.ofEpochMilli(v), java.time.ZoneOffset.UTC);
            }
        }
        throw new IllegalArgumentException("responseTime 格式不正确，期望 yyyy-MM-dd HH:mm:ss 或 epoch");
    }
}
